/*
 * File Created: 2022-07-18 10:10:58
 * Author: yubaolin (yubaolin6@outlook.com)
 * Desc: 子应用渲染，vite构建需要安装vite-plugin-qiankun插件，测试时版本1.0.14才会导出update钩子函数供主应用使用
 * Last Modified: 2022-07-18 10:11:03
 * Modified By: yubaolin (yubaolin6@outlook.com>)
 */
import {renderWithQiankun} from 'vite-plugin-qiankun/es/helper';
import ComponentMicroApp from './components/ComponentMicroApp.vue'
import {createRouter, createWebHashHistory} from "vue-router";

/**
 *
 * @param {*} rootRouteApp 应用的App.vue组件
 * @param {*} initApp 应用初始化
 * @param {*} router 应用路由配置
 * @param {*} componentModules 以组件形式渲染的路由组件模块
 */
export default function renderMicroApp({ rootElId, rootRouteApp, initApp, routes, routerBeforeEachHook, routeAfterEachHook, comModules}) {
  // 路由挂载微应用渲染
  function routeMicroAppRender(container, appGlobal) {
    let app = createApp(rootRouteApp)
    const {routeBase} = appGlobal
    initApp(app)

    routes.forEach(item => {
      item.alias = item.path;
      item.path = [`/${ routeBase || 'design'}`, item.path].join('')
    })

    const router = createRouter({
      history: createWebHashHistory(),
      routes: routes,
      // base: reouteBase || name
    });

    router.beforeEach(routerBeforeEachHook);
    router.afterEach(routeAfterEachHook);

    app.use(router)
    if(appGlobal) {
        app.config.globalProperties.mainAppGlobal = appGlobal
    }
    app.mount(container.querySelector(`#${rootElId}`))
    console.log(app)
    return app
  }

  // 手动挂载微应用渲染，不添加路由配置，直接渲染组件
  function microAppRender(container, props, appGlobal) {
    let app = createApp(ComponentMicroApp, props)
    Object.keys(comModules).forEach(key => {
        let component = comModules[key].default
        if (component.name) {
            app.component(component.name, component)
        }
    })
    initApp(app)
    app.config.globalProperties.mainAppGlobal = appGlobal
    app.mount(container.querySelector(`#${rootElId}`))
    return app
  }

  // 缓存app
  const appMap = new Map()

  // qiankun生命函数
  renderWithQiankun({
    bootstrap(props) {
        console.log('micro-designer-bootstrap', props);
    },
    // 挂载时参数props被qiankun平铺
    mount(props) {
        console.log('micro-designer-mount', props);
        const {container, componentName, mode, routeBase, stateData, appGlobal, appId, onGlobalStateChange, setGlobalState} = props
        let app = appMap.get(appId);
        // 如果上一次挂载的app未卸载，先卸载
        if (app) {
          app.unmount()
          appMap.delete(appId)
        }

        const renderProps = reactive({
            componentName,
            stateData: {...stateData},
        })
        // 手动加载模块，相当于渲染一个组件
        if (mode == 'load') {
            app = microAppRender(container, renderProps, {appId, ...appGlobal})
        } else {
            app = routeMicroAppRender(container, {appId, routeBase, mode, ...appGlobal})
        }

        // qiank状态改变
        app.config.globalProperties.$actions = {
            onGlobalStateChange,
            setGlobalState
        }
        appMap.set(appId, app)
    },
    // 更新时参数为自己传入参数
    update(props) {
        console.log('micro-designer-update', props);
        // 手动导入才会更新
        const { componentName, stateData, appId} = props.props
        if (appMap.has(appId)) {
            const app = appMap.get(appId)
            app._instance.props.componentName = componentName
            app._instance.props.stateData = {...stateData}
        }
    },
    // 卸载时参数props被qiankun平铺
    unmount(props) {
        console.log('micro-designer-unmount', props);
        const {appId} = props
        if (appMap.has(appId)) {
            const app = appMap.get(appId)
            app && app.unmount()
            appMap.delete(appId)
        }
    },
  });
}
